/*
 * SuperText
 *
 *	SuperText is a subclass of the Text object that accepts files dragged
 * in and displays them as icons.  Double-clicking on the file icon will
 * open the file in the Workspace.  SuperText will perform properly when
 * grouped in a ScrollView via IB's "group in ScrollView" function.
 *
 * You may freely copy, distribute and reuse the code in this example.
 * This code is provided AS IS without warranty of any kind, expressed 
 * or implied, as to its fitness for any particular use.
 *
 * Copyright 1995 Ralph Zazula (rzazula@next.com).  All Rights Reserved.
 *
 */

#import "SuperText.h"
#import "FileImage.h"
#import <appkit/appkit.h>

BOOL IncludesType(const NXAtom *types, NXAtom type)
{
    if (types) while (*types) if (*types++ == type) return YES;
    return NO;
}

@implementation SuperText

- initFrame:(const NXRect *)frameRect
{
	const char *fileType[] = {NXFilenamePboardType};	
   NXSize aSize = {1.0E38, 1.0E38};
	//
	// This should be done somewhere else.  The preferred way is probably
	// just to use RTFD format anyway...
	//
   [Text registerDirective:"FileImage" forClass:[FileImage class]];
	
	[super initFrame:frameRect];
	[self setMonoFont:NO];
	[self setOpaque:YES];
   [self notifyAncestorWhenFrameChanged:YES];
	[self setVertResizable:YES];
	[self setHorizResizable:NO];
   [self setMinSize:&(frameRect->size)];
   [self setMaxSize:&aSize];
   [self setAutosizing:NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
   [self setSel:0 :0];	
	[self registerForDraggedTypes:fileType count:1];
	return self;
}

- awakeFromNib
{
	[self display];
	return self;
}

//========================================================================
//
// methods that implement dropping
//
//========================================================================

- (BOOL)readDragData:(Pasteboard *)pboard
{			
	return YES;
}

- (NXDragOperation)draggingEntered:(id <NXDraggingInfo>)sender
{
    NXDragOperation sourceMask;

    sourceMask = [sender draggingSourceOperationMask];

    if (sourceMask & NX_DragOperationLink)
		return NX_DragOperationLink;

    return NX_DragOperationNone;
}

- (BOOL)performDragOperation:(id <NXDraggingInfo>)sender
{	
	return YES;
}

- (BOOL)prepareForDragOperation:(id <NXDraggingInfo>)sender
{
	return YES;
}

- concludeDragOperation:(id <NXDraggingInfo>)sender
{
	int length;
	Pasteboard *pboard;
	char *data, *file, *tab;
	id newGraphic;

    pboard = [sender draggingPasteboard];

    if (IncludesType([pboard types], NXFilenamePboardType)) {
		[pboard readType:NXFilenamePboardType data:&data length:&length];
		file = data;
		while (file) {
			if (tab = strchr(file, '\t')) *tab = '\0';
			newGraphic = [[FileImage alloc]
				initForImage:[[Application workspace] getIconForFile:file]
				fileName:file];
				
			/* check to see if we have a selection yet, if not, make one */
			if (sp0.cp < 0) {
				int textlength = [self textLength];
				[self setSel:textlength :textlength];
			}
			[self replaceSelWithCell:newGraphic];
			file = tab ? ++tab : NULL;
		}
		[pboard deallocatePasteboardData:data length:length];
		[[self window] setDocEdited:YES];
    }
    return self;
}

- write:(NXTypedStream *)stream
{
	NXStream *theStream;
	int len;
	int maxLen;
	char *data;
	
	// do the default write:
	[super write:stream];
	// now, write the RTFD stuff to a NXStream
	theStream = NXOpenMemory(NULL,0,NX_READWRITE);
	[self writeRTFDTo:theStream];
	// now, get that data into a buffer
	NXGetMemoryBuffer(theStream, &data, &len, &maxLen);
	// and write it to the NXTypedStream that we were passed
	NXWriteTypes(stream,"i",&len);
   NXWriteArray(stream, "c", len, data);
	NXClose(theStream);
	return self;
}

- read:(NXTypedStream *)stream
{
	NXStream *theStream;
	char *data;
	int count;
	
	[super read:stream];
	NXReadTypes(stream,"i",&count);
	NX_MALLOC(data,char,count);
	NXReadArray(stream,"c", count, data);
	theStream = NXOpenMemory(NULL,0,NX_READWRITE);
	NXWrite(theStream,data,count);
	[self readRTFDFrom:theStream];
	NXClose(theStream);
	return self;
}

- (BOOL)respondsTo:(SEL)aSelector
{
//	printf("in SuperText respondsTo:\n");
	return [super respondsTo:aSelector];
}

@end
